Amazon ECR へイメージをプッシュ時に作成されたタグなしの 0.01MB のイメージはなにか調べてみた
GitHub Actions を利用して Amazon ECR への Docker イメージプッシュすると 0.01MB の小さな謎のイメージが追加されました。この理由について調べた際にいろいろ知らないことがあり勉強になったのでまとめておきます。
確認結果
- この現象は Docker Buildx の Provenance attestation を作成することに起因します
- ECR では、この情報が別のコンテナイメージとして保存され、0.01MB のイメージとして表示されます
イメージ作成を抑制するには
docker/build-push-action
の設定でprovenance: false
を指定することで、0.01MB のイメージ作成を抑制できます。
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
provenance: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
問題の発生状況
GitHub Actions を使用して Docker コンテナイメージをマルチプラットフォームでビルドし、ECR にプッシュすると以下のような状況が発生しました。
- タグなしの0.01MBイメージが追加される
- GitHub Actions で使用したアクション
- Docker build には
docker/setup-buildx-action@v3
を使用 - ECR へイメージのプッシュは
docker/build-push-action@v5
を使用
- Docker build には
本件は Provenance attestation が原因だったため先に用語を説明します。
Provenance attestation とは
SLSA(Supply chain Levels for Software Artifacts) Provenance attestation は、直訳すると「ソフトウェアのサプライチェーンレベルにおける出生証明」といったところでしょうか。この仕組みはそのままですが、ソフトウェアのサプライチェーンを追跡するために使用できます。
今回の Docker のイメージビルドに関しては以下の情報が記録されます。
- ビルドのタイムスタンプ
- ビルドのパラメータと環境
- バージョンコントロールメタデータ
- ソースコードの詳細など
詳細はDocker公式ドキュメントを参照してください。
Amazon ECR について
ECR が Provenance attestation をどのように扱うのか、また、今回はマルチプラットフォームイメージをプッシュしたこともあり仕様について調べました。
マルチプラットフォームイメージはサポートしている
ECR はマルチプラットフォームイメージをサポートしています。これにより AMD64 や ARM64 など、複数のプラットフォーム(アーキテクチャ)向けのコンテナイメージを同一のイメージ名・タグ名で管理できます。
Docker Hub では、同じタグで AMD64 と ARM64 用のイメージが提供されていることがよくあります。docker pull
やdocker run
を実行すると実行環境に適したイメージが自動的にダウンロードされます。利用する側としては便利ですよね。
Provenance attestation の扱い
現状の ECR では、Provenance attestation(ビルドの証明情報)が別のコンテナイメージとして保存されます。
ECR の正確なサポート状況や、仕様についての公開情報は見つけられませんでした。
後述しますが、Provenance attestation の作成をしない設定だと、0.01 MB のイメージが ECR に保存されなくなったため原因はこれで間違いありませんでした。
補足 いつからの話なのか?
Buildx v0.10 で SLSA Provenance attestation をサポートし、Provenance attestation の作成はデフォルトで有効設定となっています。
Note
Buildx v0.10 enables support for a minimal SLSA Provenance attestation, which requires support for OCI-compliant multi-platform images. This may introduce issues with registry and runtime support (e.g. Google Cloud Run and Lambda). You can optionally disable the default provenance attestation functionality using --provenance=false.
Release v0.10.0 · docker/buildx
GitHub Actions のアクションdocker/build-push-action
はv4
から Provenance attestation を作成するのがデフォルト動作となった。
Disable provenance by default if not set by crazy-max · Pull Request #781 · docker/build-push-action
v4.0.0 がリリースされたのは、2023 年 1 月 31 日のことでした。
イメージを ECR に保存する場合はどうしたらよいのか?
ビルドの過程を検証する上では必要な情報ですが ECR へビルドしたイメージを保存すると、この情報に該当する部分がタグなしの 0.01MB のイメージとなります。イメージになった状態からの活用方法がわかりませんでした。
現状だと意味をなしていないので以下の理由により、このイメージの作成を抑制した方が無難かなと考えています。
- 理由を知らない人が ECR のリポジトリを見たときに同じく疑問を抱くはず
- ECR コンテナイメージスキャンの課金対象がイメージ数単位のため課金対象が増える
docker/build-push-action の設定
当初のワークフロー
コンテナイメージのビルドと、ECR へプッシュ部分のワークフローです。platforms:
で AMD64 と、ARM64 を指定し、後はイメージのタグ付け設定している設定です。
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
ワークフロー全文
name: Docker Build and Push
on:
push:
env:
AWS_REGION: ap-northeast-1
DEV_REPOSITORY: dev-aws-pcluster-command
PROD_REPOSITORY: prod-aws-pcluster-command
jobs:
build-and-push:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set repository based on event
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "REPOSITORY=${{ env.PROD_REPOSITORY }}" >> $GITHUB_ENV
else
echo "REPOSITORY=${{ env.DEV_REPOSITORY }}" >> $GITHUB_ENV
fi
- name: Extract ParallelCluster version
id: extract_version
run: |
PARALLELCLUSTER_VERSION=$(grep 'ARG PARALLELCLUSTER_VERSION=' Dockerfile | cut -d'=' -f2)
echo "version=${PARALLELCLUSTER_VERSION}" >> $GITHUB_OUTPUT
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.login-ecr.outputs.registry }}/${{ env.REPOSITORY }}
tags: |
type=sha,format=short,prefix=v${{ steps.extract_version.outputs.version }}-
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
provenance: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
このワークフローで ECR へイメージがプッシュされると、タグなしの 0.01MB のイメージが作成されます。デフォルト設定だと Provenance attestation が作成されるためです。
Provenance attestation を作成しない
ECR にイメージを保存する場合に生み出されるタグなしの 0.01MB のイメージの作成を抑止するには、provenance: false
と明示する必要があります。
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
provenance: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
実行結果はこの通り、スッキリしました。
マルチプラットフォームイメージとは関係がなかった
プラットフォームは ARM64 のみにして、Provenance attestation の作成は明示的に有効にしました。
- name: Build and Push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/arm64
provenance: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
実行結果は以下の通り、0.01MB のイメージが作成されました。マルチプラットフォームイメージのビルドは関係なく、Provenance attestation を作成するか、しないか ECR へイメージをプッシュしたときに影響があることがわかりました。
おわりに
最近 GitHub CI/CD 実践ガイドを読みながら GitHub Actions に再入門したので知らないことばかりでした。
参考
- 円安を乗り越えるための Arm アーキテクチャへの移行が完了! そのプロセスを公開します - カミナシ エンジニアブログ
- docker/build-push-action v3.3.0で導入されたprovenanceオプションにまつわる問題 - chroju.dev
- Default image output from buildx v0.10 cannot run on Google Cloud Run or AWS Lambda · Issue #1533 · docker/buildx
- SLSA • Provenance
- Dockerの「マルチCPUアーキテクチャ」に対応したイメージをビルドする | DevelopersIO